﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MethodWorx.CMS.Configuration;
using StructureMap.Configuration.DSL;
using StructureMap.Pipeline;
using MethodWorx.CMS.Membership;
using MethodWorx.CMS.Linq;
using System.Data.Linq;
using MethodWorx.CMS.Content;
using MethodWorx.Core.Linq;
using MethodWorx.Core.DomainModel;
using StructureMap;
using MethodWorx.CMS.Plugins;
using MethodWorx.CMS.Administration;
using MethodWorx.CMS.Services;
using MethodWorx.CMS.Requests;
using MethodWorx.CMS.Providers;
using MethodWorx.CMS.UI.Application.Dependencies;
using MethodWorx.CMS.TemplateParser.Compiler;
using System.Configuration;

namespace MethodWorx.CMS.UI.Application
{
    public class DomainRegistry : Registry
    {
        public DomainRegistry()
        {
            this.For<HttpSessionStateBase>()
                .HybridHttpOrThreadLocalScoped()
                .Use(c => new HttpSessionStateWrapper(HttpContext.Current.Session));

            this.For<DataContext>()
                .HybridHttpOrThreadLocalScoped()
                .Use(delegate()
                         {
                             var context =
                                 new DataContext(ConfigurationManager.AppSettings["connection"] ?? "Data Source=localhost\\sqlexpress; Initial Catalog=cms; Integrated Security=sspi;");
                             context.Connection.Open();
                             return context;
                         });

            this.For<IRepositoryRegistry>()
                .HybridHttpOrThreadLocalScoped()
                .Use<StructureMapRepositoryRegistry>();

            this.For<IUnitOfWorkFactory>()
                .HybridHttpOrThreadLocalScoped()
                .Use<DomainModelUnitOfWorkFactory>();

            this.For<IUserRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqUserRepository>();

            this.For<IContentTemplateRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqContentTemplateRepository>();

            this.For<PhysicalDatabaseService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<PhysicalDatabaseService>();

            this.For<IPageTemplateRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqPageTemplateRepository>();

            this.For<IPageRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqPageRepository>();

            this.For<IApplicationSettingsRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqApplicationSettingsRepository>();

            this.For<IContentItemRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqContentItemRepository>();

            this.For<ICmsDataProvider>()
                .HybridHttpOrThreadLocalScoped()
                .Use<StructureMapCmsDataProvider>();


            this.For<SchemaService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<SchemaService>();

            this.For<ContentService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<ContentService>();


            this.For<IContentService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<ContentService>();

            this.For<ContentTemplateService>()
                .HybridHttpOrThreadLocalScoped()
                .TheDefault.Is.ConstructedBy(() =>
                    {
                        return new ContentTemplateService(ObjectFactory.GetInstance<IUnitOfWorkFactory>(), ObjectFactory.GetInstance<IContentTemplateRepository>());
                    });

            this.For<ApplicationTypeService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<ApplicationTypeService>();

            this.For<IPluginRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<PluginRepository>();

            this.For<IPluginUserDataRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqPluginUserDataRepository>();

            this.For<IPreviewSessionRepository>()
                .HybridHttpOrThreadLocalScoped()
                .Use<LinqPreviewSessionRepository>();

            this.For<HostedApplicationService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<HostedApplicationService>();

            this.For<IUserService>()
                .HybridHttpOrThreadLocalScoped()
                .Use<UserService>();

            this.For<HostedApplicationConfigurationValues>()
                .Singleton()
                .TheDefault.Is.ConstructedBy(() =>
                    {
                        return (HostedApplicationConfigurationValues)System.Web.Configuration.WebConfigurationManager.GetSection("HostedApplication");
                    });

            this.For<ITemplateCompilationProvider>()
                .HybridHttpOrThreadLocalScoped().Use(f => new TemplateCompiler((ICmsDataProvider)null));

            var propertyConfigurations = new PropertyConfiguration();
            foreach(var pc in propertyConfigurations.GetPropertyConfigurations())
            {
                this.For<IPropertyConfiguration>().HybridHttpOrThreadLocalScoped().Use(pc);
            }

        }
    }
}